/*      Reglas();
        ~Reglas();
        void agregarPais();
        void restringirVer(Pais, Pais);
        bool puedeVer?(Pais, Pais);
        Nat #paises();
        bool tieneAlgunHueco?();*/

#include "Reglas.h"
#include "MatrizRestricciones.h"

Reglas::Reglas() : estr(){
    //el constructor básico llama al constructor del vector....
    Lista<Pais> centinela;
    estr.AgregarAtras(centinela);
}

Reglas::~Reglas()
{
    //dtor(?)
}

void Reglas::agregarPais(){
    Lista<Pais> nuevo;
    estr.AgregarAtras(nuevo);
}

void Reglas::restringirVer(Pais p1, Pais p2){
    assert(p1 != p2);
    assert(p1 > 0 && p2 > 0);
    (estr[p2]).AgregarAtras(p1);
}

bool Reglas::puedeVer(Pais p1, Pais p2) const{
    assert(p1 != p2);
    assert(p1 > 0 && p2 > 0);
    bool res = true;
    aed2::Nat i;
    for (i = 0; i < estr[p2].Longitud(); i++)
        res = res && (estr[p2])[i] != p1;
    return res;
}

aed2::Nat Reglas::cantPaises() const{
    return estr.Longitud() - 1;
}

bool Reglas::tieneAlgunHueco() const{
    MatrizRestricciones matriz(this);
    bool res = false;
    Pais p;
    for (p = 1; p<=cantPaises(); p++)
        res = res or !(matriz.esConsistente(p));
    return res;
}

Reglas::IteradorNPE::IteradorNPE(const Reglas* r, Pais p) : it((*r).estr[p])
{}

Reglas::IteradorNPE Reglas::noPuedeEmitir(Pais p) const{
    return IteradorNPE(this, p);
}

bool Reglas::IteradorNPE::hayMas() const{
    return it.hayMas();
}

const Pais& Reglas::IteradorNPE::actual() const{
    return it.actual();
}

void Reglas::IteradorNPE::avanzar(){
    assert(hayMas());
    it.avanzar();
}

//Esto es de matriz, pero tiene que ir acá porque necesita que Reglas
//tenga todo funcionando. Las foward declarations no dieron resultado.
MatrizRestricciones::MatrizRestricciones(const Reglas* r) : mat((*r).cantPaises() + 1, (*r).cantPaises() + 1, true){
    //constructor dadas las reglas.
    Pais p1, p2;
    for (p1 = 1; p1 <= (*r).cantPaises(); p1++){
        Reglas::IteradorNPE it = (*r).noPuedeEmitir(p1);
        while (it.hayMas()){
            p2 = it.actual();
            prohibirEmision(p1, p2);
            it.avanzar();
        }
    }
}
